<template>
  <MainModule>
    <template #header>
      <el-row :gutter="16">
        <el-col :span="6">
          <el-form-item label="管理员名称:">
            <el-input v-model="table.param.Username" placeholder="请输入管理员名称" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="管理员ID:">
            <el-input v-model.number="table.param.UserId" placeholder="请输入管理员ID" clearable></el-input>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="角色名称:">
            <MySelect v-model="table.param.RoleList" multiple :options="roleList.data" value="Value" label="Title"
              @change="RoleListChange">
            </MySelect>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col>
          <el-button type="success" @click="GetData">查询</el-button>
          <el-button type="warning" @click="Reset">重置</el-button>
          <el-button type="primary" @click="Create">添加管理员</el-button>
        </el-col>
      </el-row>
    </template>

    <MyTable v-bind="MyTableData" :serial="(table.param.Page - 1) * table.param.PageSize + 1">
      <template #LoginSecurityConfig="{ row }">
        <el-button :type="row.LoginSecurityConfig ? 'success' : 'primary'" @click="GoogleAuth(row)">
          {{ row.LoginSecurityConfig ? '更新谷歌验证码' : '谷歌验证码验证' }}
        </el-button>
      </template>
      <template #EnableGoogleAuth="{ row }">
        <el-switch v-model="row.EnableGoogleAuth" inline-prompt size="large" active-text="是" inactive-text="否"
          @change="UpdateRowGoogleAuth(row)"></el-switch>
      </template>
      <template #ActiveGoogleAuth="{ row }">
        <el-switch v-model="row.ActiveGoogleAuth" disabled inline-prompt size="large" active-text="是"
          inactive-text="否"></el-switch>
      </template>
      <template #operation="{ row }">
        <el-button type="primary" @click="Edit(row)">编辑</el-button>
        <el-button type="warning" @click="ChangePassword(row)">修改密码</el-button>
      </template>
    </MyTable>

    <EditingDialog :fromParam="EditingParam" :GetData="GetData"></EditingDialog>
    <ChangePasswordDialog :fromParam="ChangePasswordParam" :GetData="GetData"></ChangePasswordDialog>

    <el-dialog v-model="google.modal" :title="google.title" width="400" @close="GoogleCloseReset">
      <el-form ref="googleForm" :model="google.params" :rules="google.rules" label-width="100">
        <el-form-item :label="t('rbacManager.GoogleKey')" required prop="Seed">
          <el-input v-model.trim="google.params.Seed" :placeholder="t('placeholder.input')">
            <template #suffix>
              <el-button size="small" :type="!google.qrcode ? 'primary' : 'success'" @click="CreateQrCode">
                {{ !google.qrcode ? t('rbacManager.CreateQrCode') : t('rbacManager.UpdateQrCode') }}
              </el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item :label="t('rbacManager.GoogleCode')" required prop="Code" v-if="google.qrcode">
          <el-input v-model="google.params.Code" :placeholder="t('placeholder.input')"></el-input>
        </el-form-item>
      </el-form>
      <a id="downloadImg" v-show="google.qrcode">
        <div id="qrcode" class="qrcode" ref="qrcodeRef"></div>
      </a>
      <div slot="footer" class="modal-footer">
        <el-button @click="GoogleCloseReset">{{ t('button.cancel') }}</el-button>
        <el-button type="primary" @click="GoogleSubmit(googleForm)">{{ t('button.submit') }}</el-button>
        <el-button type="success" v-if="google.qrcode" @click="SaveQrCode">{{ t('rbacManager.SaveQrCode') }}</el-button>
      </div>
    </el-dialog>

    <template #footer>
      <MyPagination :total="table.total" v-model:currentPage="table.param.Page" v-model:pageSize="table.param.PageSize"
        @change="GetData"></MyPagination>
    </template>
  </MainModule>
</template>

<script lang="ts" setup>
import { MainModule, MyPagination, MySelect, MyTable, type MyTableType } from "@/components"
import { ref, reactive, onMounted, nextTick, onUnmounted, } from 'vue';
import { type FormInstance } from 'element-plus'
import { CreateBindQrCode } from '@/library/utils/tools'
import { UserApiUrl, UserApi } from '@/api/permession/user'
import { PermessionApiUrl, PermessionApi } from '@/api/permession'
import { GoogleAuthApi } from '@/api/permession/googleAuth'
import { PermessionUser } from "./Def"
import { columns } from "./ConfigData"
import EditingDialog from './EditingDialog.vue';
import ChangePasswordDialog from './ChangePasswordDialog.vue';
import useI18n from "@/hooks/useI18n";
import { useMainLoading } from "@/hooks/useMainLoading"
import { AbortApi } from "@/library/utils/request";
import MessageUti from "@/library/utils/MessageUti"

const t = useI18n()
const { openMainLoading, closeMainLoading } = useMainLoading()

const roleList = reactive<PermessionUser.RoleListState>({
  data: []
})

const param = reactive<PermessionUser.ParamState>({
  Username: "",
  UserId: undefined,
  RoleList: [],
  Page: 1,
  PageSize: 40
})

const table = reactive<PermessionUser.TableState>({
  param: { ...param },
  total: 0,
})

// 表格配置数据
const MyTableData = reactive<MyTableType>({
  loading: false,
  table: {
    data: []
  },
  columns
})

// EditingDialog 需要的参数数据
const EditingParam = reactive<PermessionUser.EditingDialog>({
  modal: false,
  roleList: roleList,
  row: null
})

// ChangePasswordDialog 需要的参数数据
const ChangePasswordParam = reactive<PermessionUser.ChangePasswordDialog>({
  modal: false,
  row: {
    Id: undefined,
    Password: undefined
  }
})

const GetBaseParams = async () => {
  await PermessionApi.GetParams({}).then((res: any) => {
    roleList.data = res.Data.RoleId
  })
}

const GetData = async () => {
  MyTableData.loading = true

  await UserApi.SelectUsers({ ...table.param }).then((res) => {
    res.Data.Data.forEach((item: any) => {
      item.LoginSecurityConfig = item.EnableGoogleAuth  // 同步是否启用谷歌验证状态
      item.RoleListName = item.RoleListName ? item.RoleListName : '--'
    });

    MyTableData.table.data = res.Data.Data
    table.total = res.Data.Count
    MyTableData.loading = false
  })
}

const RoleListChange = (roleList: any) => {
  table.param.RoleList = roleList
}

const Reset = () => {
  table.param = { ...param }
}

const Create = () => {
  EditingParam.modal = true
}

const Edit = (row: any) => {
  EditingParam.row = { ...row }
  EditingParam.modal = true
}

const ChangePassword = (row: any) => {
  let { Id } = row
  ChangePasswordParam.row = { Id }
  ChangePasswordParam.modal = true
}

const qrcodeRef = ref<any>()
const googleForm = ref<FormInstance>()

const googleParams = reactive<PermessionUser.GoogleParams>({
  Seed: '',
  Code: '',
  UserId: undefined,
  UserName: ''
})

const google = reactive<PermessionUser.GoogleState>({
  modal: false,
  params: { ...googleParams },
  rules: {
    Seed: [{ required: true, message: '种子随机数不能为空', trigger: 'blur' }],
    Code: [{ required: true, message: '验证码不能为空', trigger: 'blur' }]
  },
  title: '',
  qrcode: false
})

const GoogleAuth = (row: any) => {
  google.title = !row.LoginSecurityConfig ? t('rbacManager.CreateGoogleAuth') : t('rbacManager.UpdateGoogleAuth')
  google.modal = true
  google.params.UserName = row.Username
  google.params.UserId = row.Id
}

const GoogleCloseReset = () => {
  google.modal = false
  nextTick(() => {
    google.title = ''
    google.params = { ...googleParams }
    googleForm.value?.resetFields()
    google.qrcode = false
  })
}

const GoogleSubmit = async (form: FormInstance | undefined) => {
  if (!form) return
  await form.validate((valid) => {
    if (valid) {
      const { Seed, Code } = google.params
      let params = { Seed, Code }

      GoogleAuthApi.TestGoogleAuth({ ...params }).then(() => {
        MessageUti.showSuccess('测试成功')
        GoogleCloseReset()
        GetData()
      })
    }
  })
}

/**
 * @description 生成二维码
 */
const CreateQrCode = () => {
  // 只校验 Seed 规则字段
  googleForm.value?.validateField("Seed", (valid) => {
    if (valid) {
      const { Seed, UserId, UserName } = google.params
      const Api = google.qrcode ? GoogleAuthApi.UpdateGoogleAuth : GoogleAuthApi.GetGoogleAuth
      let params = { Seed, UserId }

      Api({ ...params }).then((res) => {
        let SystemName = t('rbacManager.SystemName') + "-" + process.env.VUE_APP_FLAG

        CreateBindQrCode(qrcodeRef.value, UserName, SystemName, res.Data, [150, 150])
      })

      google.qrcode = true
    }
  })
}

/**
 * @description 保存二维码
 */
const SaveQrCode = () => {
  const { UserName } = google.params;
  let img = (document.getElementById("qrcode") as HTMLElement).getElementsByTagName("img")[0];

  let canvas = document.createElement("canvas") as HTMLCanvasElement;
  canvas.width = img.width;
  canvas.height = img.height;
  (canvas.getContext("2d") as CanvasRenderingContext2D).drawImage(img, 0, 0);

  let url = canvas.toDataURL("image/png");
  let downloadImg = document.getElementById("downloadImg")

  if (downloadImg) {
    let SystemName = t('rbacManager.SystemName') + "-" + process.env.VUE_APP_FLAG

    downloadImg.setAttribute("href", url);
    downloadImg.setAttribute("download", `${SystemName}-${UserName}__谷歌身份验证二维码.png`);
    downloadImg.click();
  }
}

const UpdateRowGoogleAuth = (row: any) => {
  const { Id, EnableGoogleAuth } = row
  let params = {
    Id,
    Enable: EnableGoogleAuth
  }

  GoogleAuthApi.EnableGoogleAuthSecret({ ...params })
    .then(() => {
      GetData()
    }).
    catch(() => {
      row.EnableGoogleAuth = !row.EnableGoogleAuth
    })
}

onMounted(async () => {
  openMainLoading()
  await GetData()
  await GetBaseParams()
  closeMainLoading()
})

onUnmounted(() => {
  AbortApi([UserApiUrl.SelectUsers, PermessionApiUrl.GetParams])
})

</script>

<style lang="scss" scoped>
.pointer {
  cursor: pointer;
}

.qrcode {
  width: 150px;
  height: 150px;
  margin: 16px auto;
  padding: 8px;
  border: 1px solid #ddd;
}
</style>
